home *** CD-ROM | disk | FTP | other *** search
/ World of Video / World of Video.iso / gfxprograms / 3dprograms / t3dlib / source / writepov.c < prev    next >
C/C++ Source or Header  |  1995-02-13  |  16KB  |  544 lines

  1. /* writepov.c - dump the internal database to a POV-Ray 1.0 input file
  2.  *            - written by Glenn M. Lewis - 7/27/92
  3.  */
  4.  
  5. static char rcs_id[] = "$Id: writepov.c,v 1.7 1993/02/14 07:27:06 glewis Exp $";
  6.  
  7. #include <stdio.h>
  8. #include <ctype.h>
  9. #include <math.h>
  10. extern double sqrt();
  11. #include "t3dlib.h"
  12. #ifdef __STDC__
  13. #include <stdlib.h>
  14. #include <strings.h>
  15. #include "writepov_protos.h"
  16. #endif
  17.  
  18. static void process_DESC();
  19. static void process_EXTR();
  20. static void process_INFO();
  21. static void process_OBJ();
  22.  
  23. /* Two-space tabs */
  24. #define TABSTOP "  "
  25.  
  26. static FILE *out;
  27. static char tab[133];
  28. static int num_OBJ, num_DESC, num_TOBJ;
  29. static int cur_level, cur_objnum;
  30. static int prntline;
  31.  
  32. static struct save_hier {
  33.     int objnum;
  34.     struct save_hier *next;
  35. } *root = 0;
  36. typedef struct save_hier HIER;
  37.  
  38. /* Here are a few necessary utilities */
  39.  
  40. static void indent()
  41. {
  42.     strcat(tab, TABSTOP);
  43. }
  44.  
  45. static void outdent()
  46. {
  47.     register int i = strlen(tab) - strlen(TABSTOP);
  48.     if (i<0) {
  49.         fprintf(stderr, "Whoa, Glenn!  You blew it!\n");
  50.         tab[0] = '\0';
  51.         return;
  52.     }
  53.     tab[i] = '\0';
  54. }
  55.  
  56. static void send_XYZ(f)            /* Print a common string */
  57. XYZ_st *f;
  58. {
  59.     fprintf(out, " <%.12g",   f->x);
  60.     fprintf(out, " %.12g",    f->y);
  61.     fprintf(out, " %.12g>\n", f->z);
  62. }
  63.  
  64. static void send_RGB(rgb)            /* Print a common string */
  65. RGB_st *rgb;
  66. {
  67.     fprintf(out, " color red %.12g",   ((double)rgb->r)*(1.0/255.0));
  68.     fprintf(out, " green %.12g",   ((double)rgb->g)*(1.0/255.0));
  69.     fprintf(out, " blue %.12g ", ((double)rgb->b)*(1.0/255.0));
  70. }
  71.  
  72. /********************/
  73. /* The MAIN section */
  74. /********************/
  75.  
  76. int write_POVRay(world, file)
  77. WORLD *world;
  78. FILE *file;
  79. {
  80.     register OBJECT *o;
  81.  
  82.     if (!(out=file) || !world) return(0);    /* File not open */
  83.  
  84.     tab[0] = '\0';
  85.     num_OBJ = num_DESC = num_TOBJ = 0;
  86.  
  87.     fputs("/* TTDDD library - Written by Glenn M. Lewis - 7/27/92 */\n\n", out);
  88.     if (world->info) process_INFO(world->info);
  89.     for (o=world->object; o; o=o->next)
  90.         process_OBJ(o);
  91.     return(1);
  92. }
  93.  
  94. static void process_INFO(info)
  95. INFO *info;
  96. {
  97.     fprintf(out, "%s/* INFO Begin */\n", tab);
  98.     indent();
  99. #ifdef OLD_STUFF
  100.     for (i=0; i<8; i++)
  101.         if (info->brsh[i][0])
  102.             fprintf(out, "%sBRSH[%d]=\"%s\"\n", tab, i, info->brsh[i]);
  103.  
  104.     for (i=0; i<8; i++)
  105.         if (info->stnc[i][0])
  106.             fprintf(out, "%sSTNC[%d]=\"%s\"\n", tab, i, info->stnc[i]);
  107.  
  108.     for (i=0; i<8; i++)
  109.         if (info->txtr[i][0])
  110.             fprintf(out, "%sTXTR[%d]=\"%s\"\n", tab, i, info->txtr[i]);
  111.  
  112.     if (info->obsv) {
  113.         fprintf(out, "%seyep", tab); send_XYZ(&info->obsv->came);
  114.         fprintf(out, "%s/* OBSV Rotate", tab); send_XYZ(&info->obsv->rota);
  115.         fprintf(out, "*/%sfocaldist  %.12g\n", tab, info->obsv->foca);
  116.     }
  117. *
  118.  
  119. /*    if (info->otrk[0]) fprintf(out, "%sOTRK \"%s\"\n", tab, info->otrk);    */
  120.  
  121.  
  122.     if (info->ostr) {
  123.         if (info->ostr->path[0])
  124.             fprintf(out, "%sOSTR Path \"%s\"\n", tab, info->ostr->path);
  125.         fprintf(out, "%sOSTR Translate", tab); send_XYZ(&info->ostr->tran);
  126.         fprintf(out, "%sOSTR Rotate   ", tab); send_XYZ(&info->ostr->rota);
  127.         fprintf(out, "%sOSTR Scale    ", tab); send_XYZ(&info->ostr->scal);
  128.         i = info->ostr->info;
  129.         strin[0] = '\0';
  130.         if (i&(1<<0))  strcat(strin, " ABS_TRA");
  131.         if (i&(1<<1))  strcat(strin, " ABS_ROT");
  132.         if (i&(1<<2))  strcat(strin, " ABS_SCL");
  133.         if (i&(1<<4))  strcat(strin, " LOC_TRA");
  134.         if (i&(1<<5))  strcat(strin, " LOC_ROT");
  135.         if (i&(1<<6))  strcat(strin, " LOC_SCL");
  136.         if (i&(1<<8))  strcat(strin, " X_ALIGN");
  137.         if (i&(1<<9))  strcat(strin, " Y_ALIGN");
  138.         if (i&(1<<10)) strcat(strin, " Z_ALIGN");
  139.         if (i&(1<<12)) strcat(strin, " FOLLOW_ME");
  140.         fprintf(out, "%sOSTR Info%s\n", tab, strin);
  141.     }
  142.  
  143.     if (info->fade) {
  144.         fprintf(out, "%s/* FADE FadeAt %.12g*/\n", tab, info->fade->at);
  145.         fprintf(out, "%s/* FADE FadeBy %.12g*/\n", tab, info->fade->by);
  146.         fprintf(out, "%s/* FADE FadeTo", tab); send_RGB(&info->fade->to);
  147.         fprintf(out, "*/\n");
  148.     }
  149.  
  150.     if (info->skyc) {
  151.         fprintf(out, "%s/* SKYX Horizon", tab); send_RGB(&info->skyc->hori);
  152.         fprintf(out, "*/\n");
  153.         fprintf(out, "%s/* SKYC Zenith ", tab); send_RGB(&info->skyc->zeni);
  154.         fprintf(out, "*/\n");
  155.     }
  156.  
  157.     if (info->ambi)
  158.         { fprintf(out, "%sbackground", tab); send_RGB(info->ambi); }
  159.  
  160.  
  161.     if (info->glb0)
  162.         for (i=0; i<8; i++)
  163.             fprintf(out, "%sGLB0[%d]=%u\n", tab, i, info->glb0[i]);
  164. #endif
  165.  
  166.     outdent();
  167.     fprintf(out, "%s/* End INFO */\n", tab);
  168. }
  169.  
  170. static void process_OBJ(obj)
  171. register OBJECT *obj;
  172. {
  173.     register HIER *p;
  174.     num_OBJ++;
  175.     fprintf(out, "%s/* OBJ Begin \"Hierarchy %d\" */\n", tab, num_OBJ);
  176.     fprintf(out, "%sobject {\n", tab);
  177.     num_DESC = num_TOBJ = 0;        /* Reset counters */
  178.     cur_level = 0;
  179.     cur_objnum = 1;
  180.     prntline = 1;
  181.  
  182.     if (obj->extr) process_EXTR(obj->extr);
  183.     else process_DESC(obj);
  184.  
  185.     while (root) {                /* This should happen at most once. */
  186.         p = root->next;
  187.         free((char *)root);        /* Delete this from list */
  188.         root = p;
  189.         outdent();
  190.     }
  191.  
  192.     fprintf(out, "%s/* End OBJ   \"Hierarchy %d\" */\n", tab, num_OBJ);
  193.     fprintf(out, "%s}\n", tab);
  194. }
  195.  
  196. static void process_TOBJ()
  197. {
  198.     register HIER *p;
  199.     if (num_DESC-num_TOBJ < cur_level) {    /* Pop old level off HIER */
  200.         cur_level--;
  201.         cur_objnum = root->objnum;
  202.         p = root->next;
  203.         free((char *)root);    /* Delete from list */
  204.         root = p;
  205.         outdent();    /* Pretty file formatting */
  206.     }
  207.     fprintf(out, "%s/* TOBJ       \"Object %d at level %d of hierarchy %d\" */\n",
  208.         tab, cur_objnum-1, num_DESC-num_TOBJ, num_OBJ);
  209.     fprintf(out, "%s}\n", tab);
  210.     num_TOBJ++;
  211.     prntline = 1;
  212. }
  213.  
  214. static void process_EXTR(extr)
  215. EXTR *extr;
  216. {
  217.     if (!prntline) fprintf(out, "\n");    /* Print one anyway */
  218.     indent();
  219.     num_DESC++;
  220.  
  221.     fprintf(out, "%s/* EXTR Begin \"Object %d at level %d of hierarchy %d\" */\n",
  222.         tab, cur_objnum, num_DESC-num_TOBJ, num_OBJ);
  223.     fprintf(out, "%sunion {\n", tab);
  224.     indent();
  225.     fprintf(out, "%s/* LOAD \"%s\" */\n", tab, extr->filename);
  226.     fprintf(out, "#include \"%s\"\n", extr->filename);
  227.     fprintf(out, "%stranslate", tab); send_XYZ(&extr->mtrx.tran);
  228.     fprintf(out, "%sscale    ", tab); send_XYZ(&extr->mtrx.scal);
  229.     fprintf(out, "%s/* transform", tab);
  230.     fprintf(out, " %.12g %.12g %.12g",
  231.         extr->mtrx.rota1.x,
  232.         extr->mtrx.rota1.y,
  233.         extr->mtrx.rota1.z);
  234.     fprintf(out, " %.12g %.12g %.12g",
  235.         extr->mtrx.rota2.x,
  236.         extr->mtrx.rota2.y,
  237.         extr->mtrx.rota2.z);
  238.     fprintf(out, " %.12g %.12g %.12g",
  239.         extr->mtrx.rota3.x,
  240.         extr->mtrx.rota3.y,
  241.         extr->mtrx.rota3.z);
  242.     fprintf(out, "*/\n");
  243.  
  244.     outdent();
  245.     fprintf(out, "%s/* End EXTR   \"Object %d at level %d of hierarchy %d\" */\n",
  246.         tab, cur_objnum, num_DESC-num_TOBJ, num_OBJ);
  247.     fprintf(out, "%s}\n", tab);
  248.  
  249.     num_TOBJ++;
  250.     cur_objnum++;
  251.     outdent();
  252.     prntline = 1;
  253. }
  254.  
  255. static void process_DESC(object)
  256. OBJECT *object;
  257. {
  258.     register int i;
  259.     register XYZ_st *p1, *p2, *p3;
  260.     register HIER *p;
  261.     register OBJECT *obj;
  262.     register DESC *desc = object->desc;
  263.  
  264.     num_DESC++;
  265.     if (num_DESC-num_TOBJ > cur_level) {    /* Push new level in HIER */
  266.         if (!prntline) fprintf(out, "\n");    /* Print one anyway */
  267.         if (!(p = (HIER*)malloc(sizeof(HIER)))) {
  268.             fprintf(stderr, "ERROR!  Out of memory.\n*** ABORT ***\n");
  269.             exit(20);
  270.         }
  271.         p->next = root;        /* Insert into list */
  272.         root = p;
  273.         root->objnum = cur_objnum;
  274.         cur_level++;
  275.         cur_objnum = 1;
  276.         indent();    /* Pretty file formatting */
  277.     }
  278.  
  279.     if (desc->shap && desc->shap[1]>0) {
  280.         fprintf(out, "%slight_source", tab);
  281.         if (desc->colr) send_RGB(desc->colr); /* else fprintf(out, " 1.0 "); */
  282.         if (desc->shap[1]==1)    /* Sunlight */
  283.             fprintf(out, "point_at < %.12g %.12g %.12g >\n",
  284.                 -(desc->posi->x),
  285.                 -(desc->posi->y),
  286.                 -(desc->posi->z));
  287.         else    /* Like a lamp */
  288.             fprintf(out, "point < %.12g %.12g %.12g >\n",
  289.                 desc->posi->x,
  290.                 desc->posi->y,
  291.                 desc->posi->z);
  292.         if (!desc->pcount && !desc->ecount && !object->child) goto SKIP_REST_LIGHT;
  293.     }
  294.  
  295.     fprintf(out,"%s/* DESC Begin \"Object %d at level %d of hierarchy %d\" */\n",
  296.         tab, cur_objnum, num_DESC-num_TOBJ, num_OBJ);
  297.     fprintf(out, "%sunion {\n", tab);
  298.     indent();
  299.  
  300.     if (desc->name[0]) fprintf(out, "%s/* name \"%s\" */\n", tab, desc->name);
  301.  
  302.     if (desc->shap) {
  303.         fprintf(out, "%s/* SHAP Shape = %u */\n", tab, desc->shap[0]);
  304.         if (desc->shap[0]==0 && !desc->shap[1]) {    /* Sphere */
  305.             fprintf(out, "%ssphere {", tab);
  306.             send_XYZ(desc->posi);
  307.             fprintf(out, "%s%.12g }\n", tab, desc->size->x);
  308.             goto SKIP_REST;
  309.         }
  310.         fprintf(out, "%s/* SHAP Lamp  = %u */\n", tab, desc->shap[1]);
  311.     }
  312.  
  313. /*
  314.     if (desc->axis) {
  315.         fprintf(out, "%sAXIS XAxis", tab); send_XYZ(&desc->axis->xaxi);
  316.         fprintf(out, "%sAXIS YAxis", tab); send_XYZ(&desc->axis->yaxi);
  317.         fprintf(out, "%sAXIS ZAxis", tab); send_XYZ(&desc->axis->zaxi);
  318.     }
  319.  
  320.     if (desc->size)
  321.         { fprintf(out, "%sSIZE", tab); send_XYZ(desc->size); }
  322.  
  323.     if (desc->pcount) {
  324.         fprintf(out, "%sPNTS PCount %u\n", tab, desc->pcount);
  325.         for (i=0; i<desc->pcount; i++) {
  326.             fprintf(out, "%sPNTS Point[%d]", tab, i);
  327.             send_XYZ(&desc->pnts[i]);
  328.         }
  329.     }
  330.  
  331.     if (desc->ecount) {
  332.         fprintf(out, "%sEDGE ECount %u\n", tab, desc->ecount);
  333.         for (i=0; i<desc->ecount; i++) {
  334.             fprintf(out, "%sEDGE Edge[%d] %u %u\n", tab, i,
  335.                 desc->edge[i<<1], desc->edge[(i<<1)+1]);
  336.         }
  337.     }
  338. */
  339.  
  340.     if (desc->fcount && desc->ecount && desc->pcount) {
  341.         fprintf(out, "%s/* FACE TCount %u */\n", tab, desc->fcount);
  342.         for (i=0; i<desc->fcount; i++) {
  343. /*            fprintf(out, "%sFACE Connect[%u] %u %u %u\n", tab, i,
  344.                 desc->face[i*3], desc->face[i*3+1], desc->face[i*3+2]);
  345. */
  346.             /* First check and see if the triangle is degenerate */
  347.             p1 = &desc->pnts[desc->edge[(desc->face[i*3])<<1]];
  348.             p2 = &desc->pnts[desc->edge[((desc->face[i*3])<<1)+1]];
  349.             if (desc->edge[(desc->face[i*3+2])<<1] ==
  350.                 desc->edge[(desc->face[i*3])<<1] ||
  351.                 desc->edge[(desc->face[i*3+2])<<1] ==
  352.                 desc->edge[((desc->face[i*3])<<1)+1])
  353.                 p3 = &desc->pnts[desc->edge[((desc->face[i*3+2])<<1)+1]];
  354.             else
  355.                 p3 = &desc->pnts[desc->edge[(desc->face[i*3+2])<<1]];
  356.             if (!((p1->x==p2->x && p1->y==p2->y && p1->z==p2->z) ||
  357.                   (p1->x==p3->x && p1->y==p3->y && p1->z==p3->z) ||
  358.                   (p2->x==p3->x && p2->y==p3->y && p2->z==p3->z))) {
  359.                 fprintf(out, "%striangle {\n", tab);
  360.                 send_XYZ(p1);
  361.                 send_XYZ(p2);
  362.                 send_XYZ(p3);
  363.     /* Print texture properties for each triangle because POV-Ray does
  364.      * not yet support object hierarchies very cleanly, IMHO.
  365.      */
  366.     if (desc->colr || desc->refl || desc->tran ||
  367.         desc->clst || desc->rlst || desc->tlst) {
  368.         fprintf(out, "%stexture {", tab);
  369.         if (desc->clst) { send_RGB((RGB_st*)&desc->clst[i*3]); fputc('\n', out);
  370.         } else if (desc->colr) { send_RGB(desc->colr); fputc('\n', out); }
  371.         if (desc->rlst) {
  372.             fprintf(out, "%sspecular %.12g\n", tab,
  373.                 (1.0/255.0) *
  374.                 sqrt((double)desc->rlst[i*3+0] * desc->rlst[i*3+0] +
  375.                      (double)desc->rlst[i*3+1] * desc->rlst[i*3+1] +
  376.                      (double)desc->rlst[i*3+2] * desc->rlst[i*3+2]));
  377.         } else if (desc->refl) {
  378.             fprintf(out, "%sspecular %.12g\n", tab,
  379.                 (1.0/255.0) *
  380.                 sqrt((double)desc->refl->r * desc->refl->r +
  381.                      (double)desc->refl->g * desc->refl->g +
  382.                      (double)desc->refl->b * desc->refl->b));
  383.         }
  384.         if (desc->tlst) {
  385.             fprintf(out, "%srefraction %.12g\n", tab,
  386.                 (1.0/255.0) *
  387.                 sqrt((double)desc->tlst[i*3+0] * desc->tlst[i*3+0] +
  388.                      (double)desc->tlst[i*3+1] * desc->tlst[i*3+1] +
  389.                      (double)desc->tlst[i*3+2] * desc->tlst[i*3+2]));
  390.         } else if (desc->tran) {
  391.             fprintf(out, "%srefraction %.12g\n", tab,
  392.                 (1.0/255.0) *
  393.                 sqrt((double)desc->tran->r * desc->tran->r +
  394.                      (double)desc->tran->g * desc->tran->g +
  395.                      (double)desc->tran->b * desc->tran->b));
  396.         }
  397.         fprintf(out, "%s}\n", tab);
  398.     }
  399.                 fprintf(out, "%s}\n", tab);
  400.             }
  401.         }
  402.     }
  403.  
  404. SKIP_REST:
  405.  
  406.     for (obj=object->child; obj; obj=obj->next) {
  407.         if (obj->extr) process_EXTR(obj->extr);
  408.         else process_DESC(obj);
  409.     }
  410.  
  411.     outdent();
  412.     fprintf(out, "%s/* End DESC   \"Object %d at level %d of hierarchy %d\" */\n",
  413.         tab, cur_objnum, num_DESC-num_TOBJ, num_OBJ);
  414.  
  415.     if (desc->posi)
  416.         { fprintf(out, "%stranslate", tab); send_XYZ(desc->posi); }
  417.  
  418. /*
  419.     if (desc->colr || desc->refl || desc->tran) {
  420.         fprintf(out, "%stexture {", tab);
  421.         if (desc->colr) { send_RGB(desc->colr); fputc('\n', out); }
  422.         if (desc->refl) {
  423.             fprintf(out, "%sspecular %.12g\n", tab,
  424.                 (1.0/255.0) *
  425.                 sqrt((double)desc->refl->val[0] * desc->refl->val[0] +
  426.                      (double)desc->refl->val[1] * desc->refl->val[1] +
  427.                      (double)desc->refl->val[2] * desc->refl->val[2]));
  428.         }
  429.         if (desc->tran) {
  430.             fprintf(out, "%srefraction %.12g\n", tab,
  431.                 (1.0/255.0) *
  432.                 sqrt((double)desc->tran->val[0] * desc->tran->val[0] +
  433.                      (double)desc->tran->val[1] * desc->tran->val[1] +
  434.                      (double)desc->tran->val[2] * desc->tran->val[2]));
  435.         }
  436.         fprintf(out, "%s}\n", tab);
  437.     }
  438. */
  439.  
  440. #ifdef WRITETTDDD
  441.     if (desc->fcount) {
  442.         fprintf(out, "%sCLST Count %u\n", tab, i);
  443.         for (i=0; i<desc->fcount; i++) {
  444.             if (desc->colr) {
  445.                 if (desc->clst[i*3  ]==desc->colr->val[0] &&
  446.                     desc->clst[i*3+1]==desc->colr->val[1] &&
  447.                     desc->clst[i*3+2]==desc->colr->val[2]) continue; /* Skip */
  448.             } else {
  449.                 if (desc->clst[i*3  ]==255 &&
  450.                     desc->clst[i*3+1]==255 &&
  451.                     desc->clst[i*3+2]==255) continue;    /* Skip this one */
  452.             }
  453.             fprintf(out, "%sCLST Color[%u]", tab, i);
  454.             send_RGB((RGB_st*)&desc->clst[i*3]);
  455.         }
  456.         fprintf(out, "%sRLST Count %u\n", tab, i);
  457.         for (i=0; i<desc->fcount; i++) {
  458.             if (desc->refl) {
  459.                 if (desc->rlst[i*3  ]==desc->refl->val[0] &&
  460.                     desc->rlst[i*3+1]==desc->refl->val[1] &&
  461.                     desc->rlst[i*3+2]==desc->refl->val[2]) continue; /* Skip */
  462.             } else {
  463.                 if (desc->rlst[i*3  ]==0 &&
  464.                     desc->rlst[i*3+1]==0 &&
  465.                     desc->rlst[i*3+2]==0) continue;    /* Skip this one */
  466.             }
  467.             fprintf(out, "%sRLST Color[%u]", tab, i);
  468.             send_RGB((RGB_st*)&desc->rlst[i*3]);
  469.         }
  470.         fprintf(out, "%sTLST Count %u\n", tab, i);
  471.         for (i=0; i<desc->fcount; i++) {
  472.             if (desc->tran) {
  473.                 if (desc->tlst[i*3  ]==desc->tran->val[0] &&
  474.                     desc->tlst[i*3+1]==desc->tran->val[1] &&
  475.                     desc->tlst[i*3+2]==desc->tran->val[2]) continue; /* Skip */
  476.             } else {
  477.                 if (desc->tlst[i*3  ]==0 &&
  478.                     desc->tlst[i*3+1]==0 &&
  479.                     desc->tlst[i*3+2]==0) continue;    /* Skip this one */
  480.             }
  481.             fprintf(out, "%sTLST Color[%u]", tab, i);
  482.             send_RGB((RGB_st*)&desc->tlst[i*3]);
  483.         }
  484.     }
  485. #endif
  486.  
  487.     if (desc->tpar) {
  488.         for (i=0; i<16; i++)
  489.             fprintf(out, "%s/* TPAR[%u]=%.12g */\n", tab, i, desc->tpar[i]);
  490.     }
  491.  
  492.     if (desc->surf) {
  493.         for (i=0; i<5; i++)
  494.             fprintf(out, "%s/* SURF[%u]=%d */\n", tab, i, desc->surf[i]);
  495.     }
  496.  
  497.     if (desc->mttr) {
  498.         fprintf(out, "%s/* MTTR Type =%u */\n", tab, desc->mttr->type);
  499.         fprintf(out, "%s/* MTTR Index=%.12g */\n", tab, (double)desc->mttr->indx);
  500.     }
  501.  
  502.     if (desc->spec) {
  503.         fprintf(out, "%s/* SPEC Spec=%u */\n", tab, desc->spec[0]);
  504.         fprintf(out, "%s/* SPEC Hard=%u */\n", tab, desc->spec[1]);
  505.     }
  506.  
  507.     if (desc->prp0) {
  508.         for (i=0; i<6; i++)
  509.             fprintf(out, "%s/* PRP0[%u]=%u */\n", tab, i, desc->prp0[i]);
  510.     }
  511.  
  512.     if (desc->ints)
  513.         fprintf(out, "%s/* INTS=%.12g */\n", tab, desc->ints);
  514.  
  515. #ifdef WRITETDDD
  516.     if (desc->stry) {
  517.         fprintf(out, "%sSTRY Path \"%s\"\n", tab, desc->stry->path);
  518.         fprintf(out, "%sSTRY Translate", tab); send_XYZ(&desc->stry->tran);
  519.         fprintf(out, "%sSTRY Rotate   ", tab); send_XYZ(&desc->stry->rota);
  520.         fprintf(out, "%sSTRY Scale    ", tab); send_XYZ(&desc->stry->scal);
  521.         i = desc->stry->info;
  522.         strin[0] = '\0';
  523.         if (i&(1<<0))  strcat(strin, " ABS_TRA");
  524.         if (i&(1<<1))  strcat(strin, " ABS_ROT");
  525.         if (i&(1<<2))  strcat(strin, " ABS_SCL");
  526.         if (i&(1<<4))  strcat(strin, " LOC_TRA");
  527.         if (i&(1<<5))  strcat(strin, " LOC_ROT");
  528.         if (i&(1<<6))  strcat(strin, " LOC_SCL");
  529.         if (i&(1<<8))  strcat(strin, " X_ALIGN");
  530.         if (i&(1<<9))  strcat(strin, " Y_ALIGN");
  531.         if (i&(1<<10)) strcat(strin, " Z_ALIGN");
  532.         if (i&(1<<12)) strcat(strin, " FOLLOW_ME");
  533.         fprintf(out, "%sSTRY Info%s\n", tab, strin);
  534.     }
  535. #endif
  536.  
  537. SKIP_REST_LIGHT:
  538.  
  539.     cur_objnum++;
  540.     prntline = 0;
  541.     process_TOBJ();
  542. }
  543.  
  544.